/*******************************************
Module: zt_daemon.c
E-Mail: 24zhutian@gmail.com
Notices: Copyright (c) 2007-2011 ls
*******************************************/
#include "zt_config.h"
#include "zt_daemon.h"

#ifdef _MSC_VER
ZT_API int	zt_daemon(int nochdir, int noclose)
{
	return(ZT_OK);
}
#else
ZT_API int	zt_daemon(int nochdir, int noclose)
{
	struct sigaction osa, sa;
	int fd;
	pid_t newgrp;
	int oerrno;
	int osa_ok;

	/* A SIGHUP may be thrown when the parent exits below. */
	sigemptyset(&sa.sa_mask);
	sa.sa_handler = SIG_IGN;
	sa.sa_flags = 0;
	osa_ok = sigaction(SIGHUP, &sa, &osa);

	switch (fork()) {
	case -1:
		return (-1);
	case 0:
		break;
	default:
		/*
		 * A fine point:  _exit(0), not exit(0), to avoid triggering
		 * atexit(3) processing
		 */
		_exit(0);
	}

	newgrp = setsid();
	oerrno = errno;
	if (osa_ok != -1){
		sigaction(SIGHUP, &osa, NULL);
	}

	if (newgrp == -1) {
		errno = oerrno;
		return (ZT_ERR);
	}

	if (!nochdir){
		(void)chdir("/");
	}

	if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
		(void)dup2(fd, STDIN_FILENO);
		(void)dup2(fd, STDOUT_FILENO);
		(void)dup2(fd, STDERR_FILENO);
		if (fd > 2){
			(void)close(fd);
		}
	}
	return (ZT_OK);
}
#endif